import { TelegramClient, Api } from 'telegram'
import { StringSession, StoreSession } from 'telegram/sessions'
import Config from "@/utils/config"

export default class GramClient {
  constructor(account) {
    this.account = account
    const strSession = new StringSession(account.session)
    this.client = new TelegramClient(strSession, Config.API_ID, Config.API_HASH, {
      connectionRetries: 3,
      useWSS: true,
      timeout: 20,
    })
    this.isAuth = false
    // 如果有错误发生，error保存最后的错误
    this.error = null;
  }

  /**
   * 连接、auth校验
   * @returns isAuth
   */
  async open() {
    try {
      await this.client.connect()
      const isAuth = await this.client.checkAuthorization()
      this.isAuth = isAuth;
      return isAuth;
    } catch (error) {
      this.isAuth = false
      this.error = error
      console.error(error)
      return false;
    }
  }

  /**
   * 关闭连接退出client
   */
  async close() {
    this.isAuth = false
    try {
      await this.client.disconnect()
      await this.client.destroy()
    } catch (error) {
      console.error(error)
    }
  }

  async joinChannel(channelName) {
    if (this.isAuth != true) {
      return false;
    }
    try {
      const channelEntity = await this.client.getEntity(channelName);
      const joinResult = await this.client.invoke(
        new Api.channels.JoinChannel({ channel: channelEntity })
      )
      console.log("joinChannel result: ", joinResult)
      return true
    } catch (error) {
      console.error(error)
      this.error = error
      return false
    }
  }

  async getEntity(peerName) {
    if (this.peerMap == null) {
      this.peerMap = {}
    }
    if (this.peerMap[peerName] == null) {
      try {
        const peer = await this.client.getInputEntity(peerName);
        this.peerMap[peerName] = peer
        return peer
      } catch (error) {
        this.error = error
        console.error("getInputEntity", error)
        return null
      }
    }
    const peer = this.peerMap[peerName]
    return peer
  }

  async startBot(bot, startParam) {
    if (this.isAuth != true) {
      return false;
    }
    try {
      const user = await this.getEntity(bot);
      const params = {
        bot: bot,
        peer: user,
        randomId: Date.now(),
        startParam: startParam || "abc",
      }
      const result = await this.client.invoke(
        new Api.messages.StartBot(params)
      );
      console.log("startBot", result)
      return true;
    } catch (error) {
      this.error = error
      console.error("startBot", error)
      return false;
    }
  }

  async getBotStartUrl(bot) {
    const botEntity = await this.getEntity(bot);
    for await (const message of this.client.iterMessages(botEntity, {})) {
      const replyMarkup = message.replyMarkup || []
      if (replyMarkup.length == 0) {
        continue
      }
      for (let index = 0; index < replyMarkup.rows.length; index++) {
        const element = replyMarkup.rows[index];
        const buttons = element.buttons || []
        if (buttons.length == 0) {
          continue
        }
        for (let index = 0; index < buttons.length; index++) {
          const btn = buttons[index];
          const url = btn.url
          if (url == null) {
            continue
          }
          return url
        }
      }
    }
  }

  /**
   * 获得游戏的tgweb-url
   * @param {*} bot 游戏机器人
   * @param {*} aurl 游戏启动url
   * @param {*} platform ios|android
   * @param {*} startParam ?
   * @returns 错误则返回null
   */
  async getTgwebUrl(bot, aurl, platform, startParam) {
    try {
      if (aurl.startsWith("t.me/")) {
        aurl = "https://" + aurl
      }
      const user = await this.getEntity(bot);
      const params = startParam == null ? {
        peer: user,
        bot: bot,
        fromBotMenu: false,
        url: aurl,
        platform: platform || "ios",
      } : {
        peer: user,
        bot: bot,
        fromBotMenu: false,
        url: aurl,
        platform: platform || "ios",
        startParam: startParam,
      }
      const result = await this.client.invoke(
        new Api.messages.RequestWebView(params)
      );
      const url = result.url;
      return url;
    } catch (error) {
      this.error = error
      console.error(error)
      return null;
    }
  }
}